<?php

declare(strict_types=1);

namespace App\Job;

use _PHPStan_adbc35a1c\Nette\Neon\Exception;
use App\Model\Applet;
use App\Model\AppletPlayletRel;
use App\Model\Playlet;
use App\Model\PlayletEpisodes;
use GuzzleHttp\Client;
use Hyperf\AsyncQueue\Job;
use Psr\Log\LoggerInterface;
use Hyperf\Utils\ApplicationContext;
use Hyperf\Logger\LoggerFactory;
class DyReplaceDramaJob extends Job
{

    public $playet_id;

    public $applet_id;
    protected LoggerInterface $logger;


    //获取token
    public static $getTokenUrl = "https://open.douyin.com/oauth/client_token/";

    //上传图片接口，上传对应的剧目封面图
    public static $uploadImageUrl = "https://open.douyin.com/api/playlet/v2/resource/upload/";

    //编辑短剧
    public static $dramaUpdateUrl = "https://open.douyin.com/api/playlet/v2/video/edit/";

    //剧目送审
    public static $dramaReviewUrl = "https://open.douyin.com/api/playlet/v2/video/review/";
    public function __construct($playlet_id,$ids)
    {
        $container = ApplicationContext::getContainer();
        $this->logger = $container->get(LoggerFactory::class)->get('log', 'dyrevod');
        $this->ids = $ids;
        $this->playlet_id = $playlet_id;
    }

    public function handle()
    {

        $this->logger->info('开始编辑需要重新上传的抖音剧目');
        //获取此剧目需要重新审核的
        $playletEpisodesIds = $this->ids;
        try {
            //开始上传
            $playletEpisodesData = PlayletEpisodes::query()->where('is_dy_upload',3)->whereNotNull('open_video_id')->whereNotNull('dy_cloud_id')->whereIn('id',$playletEpisodesIds)->get();
            if($playletEpisodesData->isNotEmpty()){
                $this->logger->info('获取对应的短剧的Ids');
                //获取对应的短剧的Ids
                $playletData =  Playlet::query()->where(['id' => $this->playlet_id])->select(['id','name','album_id','album_status','album_version','cover'])->where(['album_status' => 3])->first();
                if(!empty($playletData)){
                    //查询关联表中的抖音小程序ID
                    $this->logger->info('查询关联表中的微信小程序ID',[$this->playlet_id]);
                    $appletPlayletRelData = AppletPlayletRel::query()->where(['playlet_id' => $this->playlet_id])->where(['applet_id' => 20000])->select(['applet_id'])->get();
                    if($appletPlayletRelData->isNotEmpty()){
                        $appletIds = array();
                        foreach ($appletPlayletRelData as $appletPlayletRelDatum){
                            $appletIds[] = $appletPlayletRelDatum->applet_id;
                        }
                        $appletIds = array_values(array_unique($appletIds));
                        //查询微信小程序的ID 获取appID 和密钥
                        $this->logger->info('查询抖音小程序的ID 获取appID 和密钥',[$appletIds]);
                        $appletInfo = Applet::query()->whereIn('id',$appletIds)->where(['type' => 2])->select(['id','name','app_id','app_secret'])->orderby('id')->first();
                        if(!empty($appletInfo)) {
                            $accessToken = $this->getDyAccessToken($appletInfo->id,$appletInfo->app_id,$appletInfo->app_secret);
                            $this->logger->info('开始遍历上传短剧剧集集数');
                            if(!empty($accessToken)){
                                if(!empty($playletData->album_id)) {
                                    $album_id = $playletData->album_id;

                                    $open_pic_id = $this->dramaImageUpload($accessToken,$playletData->cover,$appletInfo->app_id);
                                    //数据库有主从延迟，返回的open_pic_id，不能马上使用，需要等1s左右。
                                    sleep(3);

                                    $episode_info_list = array();
                                    foreach ($playletEpisodesData as $item){

                                        $episode_info_list[] =[
                                            'title' => $item->playlet_number_name,
                                            'seq'   => $item->playlet_number,
                                            'cover_list' => [$open_pic_id],
                                            'open_video_id' => $item->open_video_id
                                        ];
                                    }

                                    $episodeData = $this->dramaUpdate($accessToken,
                                        $album_id, //抖音剧目ID
                                        $episode_info_list, //剧集信息
                                        $appletInfo->app_id, //appID
                                    );

                                    if(!empty($episodeData)){
                                        //绑定抖音集数ID
                                        $episode_id_map = $episodeData['episode_id_map'];
                                        $version =  $episodeData['version'];

                                        foreach ($playletEpisodesData as $item){
                                            $playlet_number = $item->playlet_number;
                                            if(!empty($episode_id_map[$playlet_number])){
                                                $item->dy_media_status = 1;
                                                $item->dy_episodes_id = $episode_id_map[$playlet_number];
                                                $item->save();
                                            }
                                        }
                                        //短剧送审
                                        $reviewRes = $this->dramaReview($accessToken,$album_id,$appletInfo->app_id);
                                        //数据库有主从延迟
                                        sleep(3);
                                        if(!empty($reviewRes)){
                                            $playletData->album_status = 1;
                                            $playletData->album_version = $version;
                                            $playletData->save();
                                        }
                                    }else{
                                        $this->logger->error('小程序：'.$appletInfo->name.' 短剧：'.$appletInfo->name.'编辑抖音短剧失败，短剧和剧集绑定失败');
                                    }

                                }else{
                                    $this->logger->error('此剧目没有审核通过');
                                }
                            }else{
                                $this->logger->error('查询抖音小程序的token过期');
                            }
                        }else{
                            $this->logger->error('查询抖音小程序的ID 获取appID 和密钥：没有对应的抖音小程序数据');
                        }
                    }else{
                        $this->logger->error('查询关联表中的抖音小程序ID：没有对应的短剧数据');
                    }
                }else{
                    $this->logger->error('获取对应的短剧的数据：没有对应的短剧数据');
                }

            }else{
                $this->logger->info('没有数据需要上传');
            }
        }catch (\Exception $e){
            $this->logger->error('请求抖音接口|错误：' . $e->getLine() . '|' . $e->getMessage());
        }
    }
    public function dramaImageUpload($accessToken,$cover_url,$app_id){
        $params = [
            'resource_type' => 2,
            'ma_app_id' =>  $app_id,
            'image_meta' =>[
                'url' =>$cover_url,
            ]
        ];
        $uploadUrl = self::$uploadImageUrl;
        $this->logger->info('请求数据：'.PHP_EOL.var_export(['result' => $params], true));
        $this->logger->info('请求Url：'.$uploadUrl);
        //开始上传
        $uploadResult  = $this->request($params, $uploadUrl,'POST',$accessToken);
        if($uploadResult['err_no'] == 0){
            $this->logger->info('上传图片成功 返回数据：'.PHP_EOL.var_export(['result' => $uploadResult], true));
            $open_pic_id = $uploadResult['data']['image_result']['open_pic_id'];
            return $open_pic_id;
        }else{
            $this->logger->error('上传图片失败 返回数据：'.PHP_EOL.var_export(['result' => $uploadResult], true));
        }
        return false;
    }

    public function dramaUpdate($accessToken,$album_id,$episode_info_list,$app_id){
        $params = [
            'ma_app_id' =>  $app_id,
            'album_id'=>$album_id,
            'episode_info_list' =>$episode_info_list
        ];
        $updateUrl = self::$dramaUpdateUrl;
        $this->logger->info('请求数据：'.PHP_EOL.var_export(['result' => $params], true));
        $this->logger->info('请求Url：'.$updateUrl);
        //开始上传
        $updateResult  = $this->request($params, $updateUrl,'POST',$accessToken);
        if($updateResult['err_no'] == 0){
            $this->logger->info('编辑短剧成功 返回数据：'.PHP_EOL.var_export(['result' => $updateResult], true));
            return $updateResult['data'];
        }else{
            $this->logger->error('编辑短剧失败 返回数据：'.PHP_EOL.var_export(['result' => $updateResult], true));
        }
        return false;
    }

    public function dramaReview($accessToken,$album_id,$app_id){
        $params = [
            'ma_app_id' =>  $app_id,
            'album_id'=>$album_id,
        ];
        $updateUrl = self::$dramaReviewUrl;
        $this->logger->info('请求数据：'.PHP_EOL.var_export(['result' => $params], true));
        $this->logger->info('请求Url：'.$updateUrl);
        //开始上传
        $reviewResult  = $this->request($params, $updateUrl,'POST',$accessToken);
        if($reviewResult['err_no'] == 0){
            $this->logger->info('短剧送审成功 返回数据：'.PHP_EOL.var_export(['result' => $reviewResult], true));
            return $reviewResult;
        }else{
            $this->logger->error('短剧送审失败 返回数据：'.PHP_EOL.var_export(['result' => $reviewResult], true));
        }
        return false;
    }

    public function getDyAccessToken($applet_id,$app_id,$app_secret){

        $container = ApplicationContext::getContainer();

        $redis = $container->get(\Hyperf\Redis\RedisFactory::class)->get('dy');

        $key = 'dy_admin_access_token';
        $key .= $applet_id;
        $accessToken = $redis->get($key);
        if(empty($accessToken)){
            $params         = [
                'grant_type' => 'client_credential',
                'client_key'    => $app_id,
                'client_secret'   => $app_secret
            ];
            //获取token
            $accessTokenInfo     = $this->request($params, self::$getTokenUrl,'POST');
            if (!empty($accessTokenInfo['data']['access_token'])){
                $accessToken = $accessTokenInfo['data']['access_token'];
                $redis->setex($key,7100,$accessToken);
            }else{
                $accessToken = "";
            }
        }
        return $accessToken;
    }
    /**
     * 传入数组进行HTTP POST请求
     */
    function request(array $params, string $url,string $method,string $access_token = null)
    {
        $client   = new Client([
            'timeout' => 3
        ]);
        $headers       = ['Content-Type' => 'application/json'];
        if(!empty($access_token)){
            $headers['access-token'] = $access_token;
        }

        $requestParams = [
            'headers' => $headers,
        ];
        if ($method == 'GET') {
            $requestParams['query'] = $params;
        } else {
            $requestParams['json'] = $params;//json_encode($params,JSON_UNESCAPED_UNICODE);
        }
        $response = $client->request($method,$url, $requestParams);
        if ($response->getStatusCode() !== 200) {
            return '';
        }
        $result   = $response->getBody()->getContents();
        $resultArr = json_decode($result,true);
        return $resultArr;

    }
}